package org.jeecg.modules.bid.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.bid.entity.Bid;
import org.jeecg.modules.bid.entity.BidManagement;
import org.jeecg.modules.bid.service.IBidManagementService;
import org.jeecg.modules.bid.service.IBidService;
import org.jeecg.modules.bid.vo.BidVo;
import org.jeecg.modules.bid.vo.ReportVo;
import org.jeecg.modules.supplier.entity.Supplier;
import org.jeecg.modules.supplier.service.ISupplierService;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import javax.servlet.ServletOutputStream;
import org.jeecg.common.aspect.annotation.AutoLog;

@Api(tags = "报表管理22")
@RestController
@RequestMapping("/procurement/report")
@Slf4j
public class ReportController {

    @Autowired
    private IBidManagementService bidManagementService;

    @Autowired
    private ISupplierService supplierService;

    @Autowired
    private IBidService bidService;

    /**
     * 查询所有的BidManagement，并计算节约金额和节约率
     * @return Result<List<ReportVo>>
     */
    @ApiOperation("获取报表数据")
    @GetMapping("/getData")
    public Result<List<ReportVo>> getData() {
        try {
            // 查询所有的BidManagement
            List<BidManagement> bidManagementList = bidManagementService.list();

            // 转换为ReportVo列表并计算相关数据
            List<ReportVo> reportVoList = bidManagementList.stream().map(bidManagement -> {
                ReportVo reportVo = new ReportVo();
                reportVo.setBidManagement(bidManagement);

                // 计算节约金额和节约率，添加空值检查
                if (bidManagement != null && bidManagement.getBudgetAmount() != null && bidManagement.getBidPrice() != null) {
                    // 计算节约金额
                    BigDecimal savings = bidManagement.getBudgetAmount().subtract(bidManagement.getBidPrice());
                    reportVo.setSavings(savings);

                    // 计算节约率，避免除以零
                    if (bidManagement.getBudgetAmount().compareTo(BigDecimal.ZERO) > 0) {
                        BigDecimal savingsRate = savings.divide(bidManagement.getBudgetAmount(), 4, BigDecimal.ROUND_HALF_UP)
                            .multiply(new BigDecimal(100));
                        reportVo.setSavingsRate(savingsRate);
                    }
                }

                return reportVo;
            }).collect(Collectors.toList());

            return Result.OK(reportVoList);
        } catch (Exception e) {
            log.error("获取报表数据失败", e);
            Result<List<ReportVo>> result = new Result<>();
            result.error500("获取报表数据失败: " + e.getMessage());
            return result;
        }
    }
    /**

     * 调用 @GetMapping("/getData") 获得reportVoList导出报表数据为Excel
     * 包含：项目编号、项目名称、项目类目、预算金额(万元)、中标金额(万元)、节约金额(万元)、节约率、中标供应商、完成时间
     */
    @AutoLog(value = "报表管理-导出Excel")
    @ApiOperation(value = "报表管理-导出Excel", notes = "报表管理-导出Excel")
    @GetMapping(value = "/exportExcel")
    public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
        try {
            log.info("开始导出报表数据到Excel");

            // 调用getData方法获取报表数据
            Result<List<ReportVo>> result = getData();
            if (!result.isSuccess() || result.getResult() == null) {
                log.error("获取报表数据失败");
                response.setStatus(500);
                response.getWriter().write("获取报表数据失败");
                return;
            }

            List<ReportVo> reportVoList = result.getResult();

            // 创建Excel工作簿
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet("报表数据");

            // 创建表头行
            XSSFRow headerRow = sheet.createRow(0);
            String[] headers = {"项目编号", "项目名称", "项目类目", "预算金额(万元)", "中标金额(万元)", "节约金额(万元)", "节约率", "中标供应商", "完成时间"};
            for (int i = 0; i < headers.length; i++) {
                headerRow.createCell(i).setCellValue(headers[i]);
            }

            // 填充数据行
            for (int i = 0; i < reportVoList.size(); i++) {
                ReportVo reportVo = reportVoList.get(i);
                BidManagement bidManagement = reportVo.getBidManagement();
                XSSFRow dataRow = sheet.createRow(i + 1);

                // 填充各列数据，添加空值检查
                dataRow.createCell(0).setCellValue(bidManagement.getProjectNumber() != null ? bidManagement.getProjectNumber() : "");
                dataRow.createCell(1).setCellValue(bidManagement.getProjectName() != null ? bidManagement.getProjectName() : "");
                dataRow.createCell(2).setCellValue(bidManagement.getCategory() != null ? bidManagement.getCategory() : "");
                dataRow.createCell(3).setCellValue(bidManagement.getBudgetAmount() != null ? bidManagement.getBudgetAmount().toString() : "");
                dataRow.createCell(4).setCellValue(bidManagement.getBidPrice() != null ? bidManagement.getBidPrice().toString() : "");
                dataRow.createCell(5).setCellValue(reportVo.getSavings() != null ? reportVo.getSavings().toString() : "");
                dataRow.createCell(6).setCellValue(reportVo.getSavingsRate() != null ? String.format("%.2f%%", reportVo.getSavingsRate()) : "");
                dataRow.createCell(7).setCellValue(bidManagement.getWinningName() != null ? bidManagement.getWinningName() : "");

                // 完成时间格式化
                if (bidManagement.getOpeningTime() != null) {
                    dataRow.createCell(8).setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(bidManagement.getOpeningTime()));
                } else {
                    dataRow.createCell(8).setCellValue("");
                }
            }

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            String fileName = "项目成本分析.xlsx";
            response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));

            // 写入响应流
            try (ServletOutputStream outputStream = response.getOutputStream()) {
                workbook.write(outputStream);
                outputStream.flush();
            } finally {
                workbook.close();
            }

            log.info("报表数据导出成功，导出条数: {}", reportVoList.size());
        } catch (Exception e) {
            log.error("导出Excel失败", e);
            try {
                response.setStatus(500);
                response.getWriter().write("导出Excel失败: " + e.getMessage());
            } catch (IOException ex) {
                log.error("写入错误信息失败", ex);
            }
        }
    }
    /**
     * 查看所有的供应商Supplier，根据SupplierId查找所有的Bid，根据SupplierId进行分组，
     * 计算每组中标次数、参与次数、中标率、中标金额(万元)、最近参与时间
     * @return Result<List<BidVo>>
     */
    @ApiOperation("获取供应商投标统计数据")
    @GetMapping("/getSupplierBidStats")
    public Result<List<BidVo>> getSupplierBidStats() {
        try {
            log.info("开始获取供应商投标统计数据");

            // 查询所有的供应商
            List<Supplier> supplierList = supplierService.list();

            // 查询所有的投标记录
            List<Bid> allBids = bidService.list();

            // 按供应商ID分组计算统计数据
            List<BidVo> bidVoList = supplierList.stream().map(supplier -> {
                BidVo bidVo = new BidVo();
                //bidVo.setSupplierId(supplier.getId());
                bidVo.setCompanyName(supplier.getCompanyName());
                bidVo.setEngineeringCategories(supplier.getEngineeringCategories());

                // 筛选该供应商的所有投标记录
                List<Bid> supplierBids = allBids.stream()
                    .filter(bid -> supplier.getId().equals(bid.getSupplierId()))
                    .collect(Collectors.toList());

                // 计算参与次数
                int participationCount = supplierBids.size();
                bidVo.setParticipationCount(participationCount);

                // 计算中标次数
                long winningCount = supplierBids.stream()
                    .filter(bid -> bid.getIsWinning() != null && bid.getIsWinning() == 1)
                    .count();
                bidVo.setBidCount((int) winningCount);

                // 计算中标率
                BigDecimal bidRate = BigDecimal.ZERO;
                if (participationCount > 0) {
                    bidRate = new BigDecimal(winningCount)
                        .divide(new BigDecimal(participationCount), 4, BigDecimal.ROUND_HALF_UP)
                        .multiply(new BigDecimal(100));
                }
                bidVo.setBidRate(bidRate);

                // 计算中标金额总和（万元）
                BigDecimal totalBidAmount = supplierBids.stream()
                    .filter(bid -> bid.getIsWinning() != null && bid.getIsWinning() == 1 && bid.getBidPrice() != null)
                    .map(Bid::getBidPrice)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
                // 转换为万元（假设数据库中存储的是元）
                bidVo.setBidAmount(totalBidAmount.divide(new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP));

                // 获取主要类目（从供应商信息中获取）
                bidVo.setEngineeringCategories(supplier.getEngineeringCategories());

                // 计算最近参与时间
                Date latestParticipationDate = supplierBids.stream()
                    .filter(bid -> bid.getCreateTime() != null)
                    .map(Bid::getCreateTime)
                    .max(Date::compareTo)
                    .orElse(null);
                if (latestParticipationDate != null) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    bidVo.setLastParticipationDate(sdf.format(latestParticipationDate));
                }

                return bidVo;
            }).collect(Collectors.toList());

            log.info("获取供应商投标统计数据成功，共获取{}条记录", bidVoList.size());
            return Result.OK(bidVoList);
        } catch (Exception e) {
            log.error("获取供应商投标统计数据失败", e);
            Result<List<BidVo>> result = new Result<>();
            result.error500("获取供应商投标统计数据失败: " + e.getMessage());
            return result;
        }
    }

    /**
     * 导出供应商投标统计数据到Excel
     */
    @AutoLog(value = "供应商投标统计-导出Excel")
    @ApiOperation(value = "供应商投标统计-导出Excel", notes = "供应商投标统计-导出Excel")
    @GetMapping(value = "/exportSupplierBidStatsExcel")
    public void exportSupplierBidStatsExcel(HttpServletRequest request, HttpServletResponse response) {
        try {
            log.info("开始导出供应商投标统计数据到Excel");

            // 调用getSupplierBidStats方法获取统计数据
            Result<List<BidVo>> result = getSupplierBidStats();
            if (!result.isSuccess() || result.getResult() == null) {
                log.error("获取供应商投标统计数据失败");
                response.setStatus(500);
                response.getWriter().write("获取供应商投标统计数据失败");
                return;
            }

            List<BidVo> bidVoList = result.getResult();

            // 创建Excel工作簿
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet("供应商投标统计");

            // 创建表头行
            XSSFRow headerRow = sheet.createRow(0);
            String[] headers = {"供应商名称", "参与次数", "中标次数", "中标率", "中标金额(万元)", "主要类目", "最近参与"};
            for (int i = 0; i < headers.length; i++) {
                headerRow.createCell(i).setCellValue(headers[i]);
            }

            // 填充数据行
            for (int i = 0; i < bidVoList.size(); i++) {
                BidVo bidVo = bidVoList.get(i);
                XSSFRow dataRow = sheet.createRow(i + 1);

                // 填充各列数据，添加空值检查
                dataRow.createCell(0).setCellValue(bidVo.getCompanyName() != null ? bidVo.getCompanyName() : "");
                dataRow.createCell(1).setCellValue(bidVo.getParticipationCount());
                dataRow.createCell(2).setCellValue(bidVo.getBidCount());
                dataRow.createCell(3).setCellValue(bidVo.getBidRate() != null ? String.format("%.2f%%", bidVo.getBidRate()) : "");
                dataRow.createCell(4).setCellValue(bidVo.getBidAmount() != null ? bidVo.getBidAmount().toString() : "0.00");
                dataRow.createCell(5).setCellValue(bidVo.getEngineeringCategories() != null ? bidVo.getEngineeringCategories() : "");
                dataRow.createCell(6).setCellValue(bidVo.getLastParticipationDate() != null ? bidVo.getLastParticipationDate() : "");
            }

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            String fileName = "供应商参与度详细统计.xlsx";
            response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));

            // 写入响应流
            try (ServletOutputStream outputStream = response.getOutputStream()) {
                workbook.write(outputStream);
                outputStream.flush();
            } finally {
                workbook.close();
            }

            log.info("供应商投标统计数据导出成功，导出条数: {}", bidVoList.size());
        } catch (Exception e) {
            log.error("导出供应商投标统计Excel失败", e);
            try {
                response.setStatus(500);
                response.getWriter().write("导出Excel失败: " + e.getMessage());
            } catch (IOException ex) {
                log.error("写入错误信息失败", ex);
            }
        }
    }

}
